<?php

namespace App\Http\Controllers\Dynamic;

use App\LogicService\Contracts\BloodDietLogicContract;
use App\LogicService\Contracts\SamGlucoseLogicContract;
use App\Models\Dynamic\BloodDiet;
use App\Models\Dynamic\BloodMedication;
use App\Models\Dynamic\BloodMotion;
use App\Models\Dynamic\BloodTest;
use App\Models\Dynamic\BloodThreshold;
use App\Models\Dynamic\Medicalrecord;
use App\Models\Dynamic\SamGlucose;
use App\Models\Dynamic\SamReferGlucose;
use App\Models\Dynamic\SamWear;
use App\User;
use Carbon\Carbon;
use Illuminate\Http\Request;
use App\Http\Controllers\ApiController;

class BloodGlucoseController extends ApiController
{
    /**
     * @var \App\Models\Dynamic\BloodTest
     */

    protected $user;

    protected $bloodTest;

    protected $request;

    protected $medicalrecord;

    protected $bloodThreshold;

    protected $samWear;

    protected $samGlucose;

    protected $bloodDiet;

    protected $samReferGlucose;

    protected $bloodMotion;

    protected $bloodMedication;

    protected $samGlucoseLogic;

    protected $bloodDietLogic;

    /**
     * BloodGlucoseController constructor.
     * @param \App\Models\Dynamic\BloodTest $bloodTest
     * @param \Illuminate\Http\Request $request
     */
    public function __construct(BloodTest $bloodTest, Medicalrecord $medicalrecord,
                                bloodThreshold $bloodThreshold, Request $request,
                                User $user, SamWear $samWear, SamGlucose $samGlucose,
                                BloodDiet $bloodDiet, SamReferGlucose $samReferGlucose,
                                BloodMotion $bloodMotion, BloodMedication $bloodMedication,
                                SamGlucoseLogicContract $samGlucoseLogic, BloodDietLogicContract $bloodDietLogic)
    {
        parent::__construct();
        $this->user = $user;
        $this->bloodThreshold = $bloodThreshold;
        $this->medicalrecord = $medicalrecord;
        $this->bloodTest = $bloodTest;
        $this->samWear = $samWear;
        $this->samGlucose = $samGlucose;
        $this->request = $request;
        $this->bloodDiet = $bloodDiet;
        $this->samReferGlucose = $samReferGlucose;
        $this->bloodMotion = $bloodMotion;
        $this->bloodMedication = $bloodMedication;
        $this->bloodDietLogic = $bloodDietLogic;
        $this->samGlucoseLogic = $samGlucoseLogic;
    }


    public function getDynamicBloodGlucose()
    {
        $this->validate($this->request, [
            'startTime' => 'string',
            'endTime' => 'string',
            'user_id' => 'required|integer',
            'id' => 'integer'
        ]);


        $user_id = $this->request->input('user_id');
        $startTime = $this->request->input('startTime');
        $endTime = $this->request->input('endTime', Carbon::now()->toDateTimeString());
        $id = $this->request->input('id');

        $data = [];
        if (!empty($id)) {
            $samWear = $this->samWear->find($id);
            if (!empty($samWear)) {
                $startTime = $samWear->starttime;
                $user_id = $samWear->userid;
                $data['samWear'] = $samWear->toArray();
                if (!empty($samWear->endtime)) {
                    $endTime = $samWear->endtime;
                }
            }else{
                abort(400, '佩戴记录不存在!');
            }
        }

        $user = $this->user
            ->withoutGlobalScopes()
            ->select('id', 'account', 'name', 'sex')
            ->find($user_id);

        if (!$user) {
            abort(400, '用戶不存在');
        }
        $data['user'] = $user->toArray();
        //查询当前佩戴设备传递的血糖信息
        $glucose = $this->samGlucose
            ->getListByUIdByTime($user_id, $startTime, $endTime)
            ->orderBy('id', 'asc')
            ->get();

        if (($glucose->count()) != 0) {
            foreach ($glucose as $dk => $dv) {
                $new_glucose[$dk] = [(strtotime($dv['collectedtime']) + (8 * 60 * 60)) * 1000, (float)$dv['value']];
                $collectedTimes = explode(' ', $dv['collectedtime']);
                $milSec = (strtotime($dv['collectedtime']) - strtotime($collectedTimes[0] . " 00:00:00")) * 1000;
                $bak_time = explode(' ', $dv['collectedtime']);
                $key = $bak_time[0];
                $new_data[$key][] = [$milSec, (float)sprintf("%1f", $dv['value'])];
                unset($bak_time, $milSec);
            }

            $times1 = substr($glucose[$dk]['collectedtime'], 0, 10);
            $times2 = substr($glucose[0]['collectedtime'], 0, 10);
            $data['max'] = (strtotime($times1 . " 00:00:00")) * 1000;
            $data['min'] = (strtotime($times2 . "23:59:59")) * 1000;

            $new_data1 = array();
            foreach ($new_data as $nk => $nv) {
                $new_data1[] = array(
                    'type' => 'spline',
                    'name' => $nk,
                    'data' => $nv,
                    'marker' => array('enabled' => false),
                    'enableMouseTracking' => true,
                );

            }
            unset($dlucose);
            $data['glucose'] = $new_glucose;
            $data['dateGlucose'] = $new_data1;
        }


        // 高低血糖百分比
        $alls = $this->samGlucose
            ->getListByUIdByTime($user_id, $startTime, $endTime)
            ->count('id');

        $min = $this->samGlucose
            ->whereBetween('value', [0, 3.9])
            ->getListByUIdByTime($user_id, $startTime, $endTime)
            ->count();

        $max = $this->samGlucose
            ->where('value', '>=', 7.8)
            ->getListByUIdByTime($user_id, $startTime, $endTime)
            ->count();

        $data['glucoseCount'] = $glucose->count();
        $data['all'] = $alls;

        $data['minPercentage'] = $min ? sprintf('%.1f', $min / $alls * 100) : 0;
        $data['maxPercentage'] = $max ? sprintf('%.1f', $max / $alls * 100) : 0;
        $data['normalPercentage'] = sprintf('%.1f', 100 - ($data['minPercentage'] + $data['maxPercentage']));

        //获取参比
        $referGlucose = $this->samReferGlucose
            ->where('userid', '=', $user_id)
            ->whereBetween('collectedtime', [$startTime, $endTime])
            ->orderBy('id', 'desc')
            ->get()
            ->toArray();


        $newReferGlucose = [];
        if ($referGlucose) {
            foreach ($referGlucose as $rk => $rv) {
                $newReferGlucose[$rk] = array(
                    'x' => (strtotime($rv['collectedtime']) + (8 * 60 * 60)) * 1000,
                    'y' => (float)$rv['value'],
                    'attr' => (float)$rv['value'] . "(mmol/L)",
                    'marker' => ['symbol' => 'circle']
                );
            }

        }

        $data['referGlucose'] = $newReferGlucose;

        //获取用户用餐情况
        $diet = $this->bloodDiet
            ->getListUser($user_id, $startTime, $endTime)
            ->get()
            ->toArray();


        $newDiet = [];
        if ($diet) {
            foreach ($diet as $rk => $rv) {
                $newDiet[$rk] = array(
                    'x' => (strtotime($rv['diettime']) + (8 * 60 * 60)) * 1000,
                    'y' => 3,
                    'attr' => $rv['dietsituation'],
                    'marker' => ['symbol' => 'diamond']
                );
            }
        }
        $data['diet'] = $newDiet;

        //获取运动情况
        $motion = $this->bloodMotion
            ->getListUser($user_id, $startTime, $endTime)
            ->get()
            ->toArray();

        $newMotion = [];
        if ($motion) {
            foreach ($motion as $rk => $rv) {
                $newMotion[$rk] = array(
                    'x' => (strtotime($rv['motiontime']) + (8 * 60 * 60)) * 1000,
                    'y' => 4,
                    'attr' => $rv['motiontype'] . ':' . $rv['stepsnum'],
                    'marker' => ['symbol' => 'triangle-down']
                );
            }
        }
        $data['motion'] = $newMotion;

        //胰岛素使用情况

        $medicalInfo1 = $this->bloodMedication
            ->getInfoListByUser($user_id, $startTime, $endTime, 0);

        $newmedicalInfo1 = [];
        if ($medicalInfo1) {
            foreach ($medicalInfo1 as $rk => $rv) {
                $newmedicalInfo1[$rk] = array(
                    'x' => (strtotime($rv['medicationtime']) + (8 * 60 * 60)) * 1000,
                    'y' => 1,
                    'attr' => $rv['name'],
                    'marker' => ['symbol' => 'triangle']
                );
            }
        }
        $data['medicalInfo1'] = $newmedicalInfo1;


        $medicalInfo2 = $this->bloodMedication
            ->getInfoListByUser($user_id, $startTime, $endTime, 1);

        $newmedicalInfo2 = [];
        if ($medicalInfo2) {
            foreach ($medicalInfo2 as $rk => $rv) {
                $newmedicalInfo2[$rk] = array(
                    'x' => (strtotime($rv['medicationtime']) + (8 * 60 * 60)) * 1000,
                    'y' => 1,
                    'attr' => $rv['name'],
                    'marker' => ['symbol' => 'triangle']
                );
            }
        }
        $data['medicalInfo2'] = $newmedicalInfo2;


        return $this->response($data);
    }


    public function freeBloodReport()
    {
        $this->validate($this->request, [
            'startTime' => 'string',
            'endTime' => 'string',
            'user_id' => 'required|integer',
            'id' => 'integer'
        ]);


        $user_id = $this->request->input('user_id');
        $startTime = $this->request->input('startTime');
        $endTime = $this->request->input('endTime', Carbon::now()->toDateTimeString());
        $id = $this->request->input('id');

        $data = [];
        if (!empty($id)) {
            $samWear = $this->samWear->find($id);
            if (!empty($samWear)) {
                $startTime = $samWear->starttime;
                $user_id = $samWear->userid;
                $data['samWear'] = $samWear->toArray();
                if (!empty($samWear->endtime)) {
                    $endTime = $samWear->endtime;
                }
            }else{
                abort(400, '佩戴记录不存在!');
            }
        }

        //查询患者信息
        $user = $this->user
            ->withoutGlobalScopes()
            ->select('id', 'account', 'name', 'sex')
            ->find($user_id)
            ->toArray();

        if (!$user) {
            return $this->response();
        }

        //查询最高血糖和最低血糖ge
        $bloodMaxMin = $this->bloodThreshold
            ->whereUserbaseid($user_id)
            ->orderBy('id', 'desc')
            ->first();

        $user['maxBloodReport'] = '7.8';
        $user['minBloodReport'] = '3.9';
        if ($bloodMaxMin) {
            $user['maxBloodReport'] = $bloodMaxMin->redlow;
            $user['minBloodReport'] = $bloodMaxMin->greenlow;
        }
        $data['user'] = $user;

        // 转换时间戳
        $startTimeStr = strtotime($startTime);
        $lastTimeStr = strtotime($endTime);
        // 计算天数差
        $days = round(($lastTimeStr - $startTimeStr) / 3600 / 24);


        //表格数据
        $param[] = "参数（单位mmol/L）";
        $Effective[] = "有效时间/有效点";
        $gloodAVG[] = "葡萄糖平均值";
        $gloodHigh[] = "高血糖时间百分比（>11.1）";
        $gloodMidel[] = "高血糖时间百分比（>7.8）";
        $gloodMin[] = "低血糖时间百分比（<3.9）";
        $SDBG[] = "血糖水平标准差（SDBG）";
        $AUCHigh[] = "血糖曲线下面积-高血糖";
        $AUCMin[] = "血糖曲线下面积-低血糖";
        $LAGE[] = "最大血糖波动幅度（LAGE）";
        $MODD[] = "日间血糖平均绝对差（MODD）";
        $breakfastAVG[] = "早餐后2小时平均值";
        $breakfastValue[] = "早餐后2小时最小值-最大值";
        $lunchAVG[] = "午餐后2小时平均值";
        $lunchValue[] = "午餐后2小时最小值-最大值";
        $dinnerAVG[] = "晚餐后2小时平均值";
        $dinnerValue[] = "晚餐后2小时最小值-最大值";

        for ($i = $days; $i >= 0; $i--) {
            $time = date("Y-m-d", $lastTimeStr - $i * 24 * 60 * 60);
            $param[] = $time;
            $start_time = $time . ' 00:00:00';
            $end_time = $time . ' 23:59:59';
            //有效时间/有效点
            $Effective[] = $this->samGlucoseLogic->getEffective($user_id, $start_time, $end_time);

            //葡萄糖平均值
            $gloodAVG[] = $this->samGlucoseLogic->getGloodAVG($user_id, $start_time, $end_time);

            //高血糖时间百分比（>11.1）||一般高血糖 (>7.8) || 低血糖(<3.9)
            $gloodHigh[] = $this->samGlucoseLogic->getBloodThan($user_id, $start_time, $end_time, 11.1);
            $gloodMidel[] = $this->samGlucoseLogic->getBloodThan($user_id, $start_time, $end_time, 7.8, 11.1);
            $gloodMin[] = $this->samGlucoseLogic->getBloodThan($user_id, $start_time, $end_time, 0, 3.9);

            $SDBGAndLAGE = $this->samGlucoseLogic->getSDBG($user_id, $start_time, $end_time);

            $SDBG[] = $SDBGAndLAGE[0];
            $AUCHigh[] = '';
            $AUCMin[] = '';
            $LAGE[] = $SDBGAndLAGE[1];
            $MODD[] = $this->samGlucoseLogic->getMODD($user_id, $start_time, $end_time);

            $breakfaseData = $this->bloodDietLogic->getEatData($user_id, $start_time, $end_time, '1');

            $breakfastAVG[] = $breakfaseData['avg'];
            $breakfastValue[] = $breakfaseData['min'] . "/" . $breakfaseData['max'];
            $lunchData = $this->bloodDietLogic->getEatData($user_id, $start_time, $end_time, '2');
            $lunchAVG[] = $lunchData['avg'];
            $lunchValue[] = $lunchData['min'] . "/" . $lunchData['max'];
            $dinnerData = $this->bloodDietLogic->getEatData($user_id, $start_time, $end_time, '3');
            $dinnerAVG[] = $dinnerData['avg'];
            $dinnerValue[] = $dinnerData['min'] . '/' . $dinnerData['max'];
        }


        $return_data = array(
            $param,
            $Effective,
            $gloodAVG,
            $gloodHigh,
            $gloodMidel,
            $gloodMin,
            $SDBG,
            $AUCHigh,
            $AUCMin,
            $LAGE,
            $MODD,
            $breakfastAVG,
            $breakfastValue,
            $lunchAVG,
            $lunchValue,
            $dinnerAVG,
            $dinnerValue
        );
        $data['data'] = $return_data;
        return $this->response($data);
    }

    /**
     * 返回总报告  最大最小总条数 等数据
     * @return \Illuminate\Http\JsonResponse
     */

    public function generalReport()
    {
        $this->validate($this->request, [
            'startTime' => 'string',
            'endTime' => 'string',
            'user_id' => 'required|integer',
            'id' => 'integer'
        ]);


        $user_id = $this->request->input('user_id');
        $startTime = $this->request->input('startTime');
        $endTime = $this->request->input('endTime', Carbon::now()->toDateTimeString());
        $id = $this->request->input('id');

        $data = [];
        if (!empty($id)) {
            $samWear = $this->samWear->find($id);
            if (!empty($samWear)) {
                $startTime = $samWear->starttime;
                $user_id = $samWear->userid;
                $data['samWear'] = $samWear->toArray();
                if (!empty($samWear->endtime)) {
                    $endTime = $samWear->endtime;
                }
            }else{
                abort(400, '佩戴记录不存在!');
            }
        }

        //查询患者信息
        $user = $this->user
            ->withoutGlobalScopes()
            ->select('id', 'account')
            ->find($user_id)
            ->toArray();

        if (!$user) {
            return $this->response();
        }

        //获取报告总次数 最大最小值
        $general = $this->samGlucoseLogic->getAllWearData($user_id, $startTime, $endTime);
        //高血糖时间百分比（>11.1）||一般高血糖 (>7.8) || 低血糖(<3.9)
        $general['gloodHigh'] = $this->samGlucoseLogic->getBloodThan($user_id, $startTime, $endTime, 11.1);
        $general['gloodMidel'] = $this->samGlucoseLogic->getBloodThan($user_id, $startTime, $endTime, 7.8, 11.1);
        $general['gloodMin'] = $this->samGlucoseLogic->getBloodThan($user_id, $startTime, $endTime, 0, 3.9);

        return $this->response($general);
    }
}
